package cn.yzj.entity;

import com.alibaba.fastjson.JSON;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 天翼云实例对象
 *
 * @author gzkemays
 * @since 2021/2/3 10:01
 */
public class TyCloudEntity {
  /** 请求 method */
  private String verb;
  /** MD5 传输数据时夹带的内容 */
  private String content = "";
  /** 传输的数据类型 */
  private String contentType;
  /** 一般为访问的 API 接口 */
  private String resource;
  /** 当前时间 */
  private String date;
  /** 带参数据 */
  private Object data;

  public enum Methods {
    /** 天翼云对应的请求方法 */
    POST("POST"),
    GET("GET"),
    PUT("PUT"),
    HEAD("HEAD"),
    DELETE("DELETE");
    private String method;

    Methods(String method) {
      this.method = method;
    }

    public String getMethod() {
      return method;
    }
  }

  /** 请求数据类型的标准字符串（如有例外需要自己额外定义） */
  public enum ContentType {
    /** 天翼云对应的请求数据类型 */
    JSON("application/json;charset=utf-8"),
    FILE_STREAM("application/octet-stream"),
    TEXT_HTML("text/html");
    private String type;

    ContentType(String type) {
      this.type = type;
    }

    public String getType() {
      return type;
    }
  }

  interface build {
    /**
     * 构造对象
     * @return {@link #TyCloudEntity(TyCloudEntityBuilder)}
     */
    TyCloudEntity build();
  }

  public static TyCloudEntityBuilder builder() {
    return new TyCloudEntityBuilder();
  }

  private TyCloudEntity(TyCloudEntityBuilder builder) {
    this.verb = builder.verb;
    this.content = builder.content;
    this.contentType = builder.contentType;
    this.resource = builder.resource;
    this.date = builder.date;
    this.data = builder.data;
  }

  public static class TyCloudEntityBuilder implements build {
    private String verb;
    private String content = "";
    private String contentType;
    private String resource;
    private String date;
    private Object data;

    public TyCloudEntityBuilder verb(Methods methods) {
      this.verb = methods.getMethod();
      return this;
    }

    public TyCloudEntityBuilder content(String content) {
      this.content = Optional.ofNullable(content).orElse("");
      return this;
    }

    public TyCloudEntityBuilder contentType(String contentType) {
      this.contentType = contentType;
      return this;
    }

    public TyCloudEntityBuilder contentType(ContentType contentType) {
      this.contentType = contentType.getType();
      return this;
    }

    public TyCloudEntityBuilder resource(String resource) {
      this.resource = resource;
      return this;
    }

    public TyCloudEntityBuilder date(Date date) {
      SimpleDateFormat dateFormat =
          new SimpleDateFormat("EEE',' dd MMM yyyy HH:mm:ss 'GMT'", Locale.ENGLISH);
      dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
      this.date = dateFormat.format(date);
      return this;
    }

    public TyCloudEntityBuilder data(Object data) {
      if (data instanceof TyCloudParamEntity) {
        Map<Object, Object> map = new HashMap<>();
        Class<?> clazz = data.getClass();
        for (Field field : clazz.getDeclaredFields()) {
          field.setAccessible(true);
          try {
            map.put(field.getName(), field.get(data));
          } catch (IllegalAccessException e) {
            e.printStackTrace();
          }
        }
        this.data = JSON.toJSONString(map);
        return this;
      }
      this.data = JSON.toJSONString(data);
      return this;
    }

    @Override
    public TyCloudEntity build() {
      return new TyCloudEntity(this);
    }
  }

  public String getVerb() {
    return verb;
  }

  public void setVerb(String verb) {
    this.verb = verb;
  }

  public String getContent() {
    return content;
  }

  public void setContent(String content) {
    this.content = content;
  }

  public String getContentType() {
    return contentType;
  }

  public void setContentType(String contentType) {
    this.contentType = contentType;
  }

  public String getResource() {
    return resource;
  }

  public void setResource(String resource) {
    this.resource = resource;
  }

  public String getDate() {
    return date;
  }

  public void setDate(String date) {
    this.date = date;
  }

  public Object getData() {
    return data;
  }

  public void setData(Object data) {
    this.data = data;
  }

  @Override
  public String toString() {
    return "TyCloudEntity{"
        + "verb='"
        + verb
        + '\''
        + ", content='"
        + content
        + '\''
        + ", contentType='"
        + contentType
        + '\''
        + ", resource='"
        + resource
        + '\''
        + ", date='"
        + date
        + '\''
        + ", data="
        + data
        + '}';
  }
}
